package miage.m1.plugins;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;


import miage.m1.launch.Config;

public class PluginLoader {
    private static PluginLoader instance = null;
    String path;
    ArrayList<PluginMiniExcel> liste;

    // constructeur priver (seul la class elle meme peut l'appller)
    // pattron singleton
    private PluginLoader() {
        liste = new ArrayList<PluginMiniExcel>();
        PluginMiniExcel pl = null; // L'interface qu'ont vas ajouter
        File rootPlugins = new File((String)Config.getParameterByName("plugins"));
        File[] jars = rootPlugins.listFiles();
        for (int i=0;i<jars.length ;i++ ) {
            if(!jars[i].getName().endsWith(".jar"))
                continue;

            String pathToJar = jars[i].getAbsolutePath();
            JarFile jarFile = null;
            try {
                jarFile = new JarFile(pathToJar);
            } catch (IOException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
            Enumeration e = jarFile.entries();
            URLClassLoader cl = null;

            URL[] urls = null;
            try {
                urls = new URL[]{new URL("jar:file:" + pathToJar + "!/")};
            } catch (MalformedURLException e1) {
                e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
            cl = URLClassLoader.newInstance(urls);

            while (e.hasMoreElements()) {
                JarEntry je = (JarEntry) e.nextElement();
                if (je.isDirectory() || !je.getName().endsWith(".class")) {
                    continue;
                }
                // -6 because of .class
                String className = je.getName().substring(0, je.getName().length() - 6);
                className = className.replace('/', '.');
                try {
                    Class c = cl.loadClass(className);
                    if (c.isInterface()) {
                        continue;
                    }
                    try {
                        // on verifier qu'elle implemente l'interface
                        Class<?>[] interfaces = c.getInterfaces();
                        for(int k=0;k<interfaces.length;k++){

                            if(interfaces[k].equals(PluginMiniExcel.class)){
                                pl = (PluginMiniExcel) c.newInstance();
                                liste.add(pl);
                                return;
                            }
                        }



                    } catch (InstantiationException e1) {
                        e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    } catch (IllegalAccessException e1) {
                        e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    }

                } catch (ClassNotFoundException e1) {
                    e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }

            }
        }


    }

    // retourne une seule instancer de PluginLoader
    // patron singleton
    public static PluginLoader getInstance() {
        if (PluginLoader.instance == null){
            PluginLoader.instance = new PluginLoader();
        }

        return PluginLoader.instance;
    }

    public ArrayList<PluginMiniExcel> getAllPlugins() {
        return this.liste;
    }

    public static void main(String[] args) {
        PluginLoader pl = new PluginLoader();
        ArrayList<PluginMiniExcel> list = pl.getAllPlugins();
        for(ListIterator<PluginMiniExcel> pe = list.listIterator();pe.hasNext();){
            PluginMiniExcel plugin = pe.next();
        }
    }

}
